package com.i8office.android.zhihuixinwu.dagger;


import com.i8office.android.zhihuixinwu.app.App;
import com.i8office.android.zhihuixinwu.bean.ApiService;
import com.i8office.android.zhihuixinwu.bean.NewsApiService;
import com.i8office.android.zhihuixinwu.config.Constants;
import com.socks.library.KLog;

import java.io.EOFException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.concurrent.TimeUnit;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Created by pc on 2018/4/27.
 */
@Module
public class OfficeModules {
    @Singleton
    @Provides
    protected ApiService getService(ScalarsConverterFactory scalarsConverterFactory, RxJava2CallAdapterFactory callAdapterFactory, GsonConverterFactory gsonConverterFactory, OkHttpClient client) {
        return new Retrofit.Builder().baseUrl(Constants.BASE_URL)
                .addConverterFactory(scalarsConverterFactory)
                .addConverterFactory(gsonConverterFactory)
                .addCallAdapterFactory(callAdapterFactory)
                .client(client)
                .build().create(ApiService.class);
    }

    @Singleton
    @Provides
    protected NewsApiService getNewsApiService(ScalarsConverterFactory scalarsConverterFactory, RxJava2CallAdapterFactory callAdapterFactory, GsonConverterFactory gsonConverterFactory, OkHttpClient client) {
        return new Retrofit.Builder().baseUrl(Constants.BASE_URL2)
                .addConverterFactory(scalarsConverterFactory)
                .addConverterFactory(gsonConverterFactory)
                .addCallAdapterFactory(callAdapterFactory)
                .client(client)
                .build().create(NewsApiService.class);
    }

    @Singleton
    @Provides
    protected ScalarsConverterFactory getScalarsConverterFactory() {
        return ScalarsConverterFactory.create();
    }

    @Singleton
    @Provides
    protected RxJava2CallAdapterFactory getCallAdapterFactory() {
        return RxJava2CallAdapterFactory.create();
    }

    @Singleton
    @Provides
    protected GsonConverterFactory getGsonConvertFactory() {
        return GsonConverterFactory.create();
    }

    @Singleton
    @Provides
    protected OkHttpClient getClient() {
        return new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        String url = chain.request().url().toString();
                        Request newRequest = chain.request();
                        if (url.indexOf("__session__") == -1) {
                            newRequest = chain.request().newBuilder().url(chain.request().url().newBuilder().addQueryParameter("__session__", App.getSession()).build()).build();
                        }
                        return chain.proceed(newRequest);
                    }
                })
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request();
                        try {
                            Request.Builder requestBuilder = request.newBuilder();
                            //添加UUID
                            request = requestBuilder.build();
                            RequestBody requestBody = request.body();
                            String bodyStr = "null";
                            if (requestBody != null) {
                                Buffer bufferRequest = new Buffer();
                                requestBody.writeTo(bufferRequest);
                                Charset charsetRequest = Charset.forName("UTF-8");
                                MediaType contentTypeRequest = requestBody.contentType();
                                if (contentTypeRequest != null) {
                                    charsetRequest = contentTypeRequest.charset(charsetRequest);
                                }
                                if (isPlaintext(bufferRequest)) {
                                    bodyStr = bufferRequest.readString(charsetRequest);
                                }
                            }
                            final Response response = chain.proceed(request);

                            KLog.e("请求网址: \n" + request.url() + " \n " + "请求头部信息：\n" + request.headers() + "请求body信息：\n" + bodyStr + "\n响应头部信息：\n" + response.headers());

                            final ResponseBody responseBody = response.body();
                            if (responseBody == null) {
                                return response;
                            }
                            final long contentLength = responseBody.contentLength();
                            BufferedSource source = responseBody.source();
                            source.request(Long.MAX_VALUE); // Buffer the entire body.
                            Buffer buffer = source.buffer();

                            Charset charset = Charset.forName("UTF-8");
                            MediaType contentType = responseBody.contentType();
                            if (contentType != null) {
                                try {
                                    charset = contentType.charset(charset);
                                } catch (UnsupportedCharsetException e) {
                                    KLog.e("Couldn't decode the response body; charset is likely malformed.");
                                }
                            }

                            if (contentLength != 0) {
                                KLog.e("--------------------------------------------开始打印返回数据----------------------------------------------------");
                                KLog.e(buffer.clone().readString(charset));
                                KLog.e("--------------------------------------------结束打印返回数据----------------------------------------------------");
                            }
                            return response;
                        } catch (Exception e) {
                            KLog.e("打印出错,请求网址: \n" + request.url());
                            KLog.e(e == null ? "null" : e.toString());
                        }
                        return chain.proceed(chain.request());
                    }
                })
                .connectTimeout(5000, TimeUnit.MILLISECONDS)
                .readTimeout(20000, TimeUnit.MILLISECONDS).build();
        //其他配置
    }


    static boolean isPlaintext(Buffer buffer) throws EOFException {
        try {
            Buffer prefix = new Buffer();
            long byteCount = buffer.size() < 64 ? buffer.size() : 64;
            buffer.copyTo(prefix, 0, byteCount);
            for (int i = 0; i < 16; i++) {
                if (prefix.exhausted()) {
                    break;
                }
                int codePoint = prefix.readUtf8CodePoint();
                if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
                    return false;
                }
            }
            return true;
        } catch (EOFException e) {
            return false; // Truncated UTF-8 sequence.
        }
    }
}
